using FileTransfer.Client.Http.Model;
using FileTransferDesktop.Extensions;
using Microsoft.Extensions.Logging;
using ApiClient = FileTransfer.Client.ApiClient;

namespace FileTransferDesktop.Services;

public class AuthenticationService(
    IServiceProvider serviceProvider,
    ILogger<AuthenticationService> logger
) : IAuthenticationService
{
    private ApiClient Api => serviceProvider.CreateApiClient();

    public UserResponse? CurrentUser { get; private set; }
    public string? Token { get; private set; }
    public bool IsAuthenticated => !string.IsNullOrEmpty(Token) && CurrentUser != null;

    public event EventHandler<bool>? AuthenticationStatusChanged;

    public async Task<AuthResponse> LoginAsync(
        string username,
        string password,
        bool rememberMe = false
    )
    {
        try
        {
            var loginRequest = new UserLoginRequest(username, password);
            var response = await Api.UserControllerApi.LoginAsync(loginRequest);

            if (response?.Data != null)
            {
                var authResponse = response.Data;
                Token = authResponse.Token;
                CurrentUser = authResponse.User; // 保存登录状态
                SaveAuthentication(authResponse, rememberMe);

                // 保存最后登录的用户
                SaveLastLoginUser(
                    authResponse.User?.ToUserInfo() ?? new UserInfo { Username = username }
                );

                // 触发登录状态改变事件
                AuthenticationStatusChanged?.Invoke(this, true);

                logger.LogInformation("用户 {Username} 登录成功", CurrentUser?.Username);
                return authResponse;
            }

            throw new InvalidOperationException("登录响应数据为空");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "登录失败: {Username}", username);
            throw;
        }
    }

    public async Task<AuthResponse> RegisterAsync(
        string username,
        string email,
        string password,
        string displayName = ""
    )
    {
        try
        {
            var registerRequest = new UserRegistrationRequest(
                username,
                email,
                password,
                displayName
            );
            var response = await Api.UserControllerApi.RegisterAsync(registerRequest);

            if (response?.Data != null)
            {
                var authResponse = response.Data;
                Token = authResponse.Token;
                CurrentUser = authResponse.User;
                SaveAuthentication(authResponse, false);

                // 保存最后登录的用户名
                SaveLastLoginUser(
                    authResponse.User?.ToUserInfo() ?? new UserInfo { Username = username }
                );

                // 触发登录状态改变事件
                AuthenticationStatusChanged?.Invoke(this, true);

                logger.LogInformation("用户 {Username} 注册成功", username);
                return authResponse;
            }

            throw new InvalidOperationException("注册响应数据为空");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "注册失败: {Username}", username);
            throw;
        }
    }

    public Task LogoutAsync()
    {
        try
        {
            // 清除内存中的认证信息
            var username = CurrentUser?.Username;
            Token = null;
            CurrentUser = null;

            // 清除本地存储的认证信息
            ClearAuthentication();

            // 清除最后登录用户信息（可选，根据需求决定是否保留）
            // ClearLastLoginUser();

            // 触发登录状态改变事件
            AuthenticationStatusChanged?.Invoke(this, false);

            logger.LogInformation("用户 {Username} 登出成功", username);
            return Task.CompletedTask;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "登出时发生错误");
            throw;
        }
    }

    public async Task<UserResponse?> GetCurrentUserAsync()
    {
        try
        {
            if (!IsAuthenticated)
                return null;

            var response = await Api.UserControllerApi.GetCurrentUserAsync();
            if (response?.Data != null)
            {
                CurrentUser = response.Data;
                return CurrentUser;
            }

            return null;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取当前用户信息失败");
            // 如果获取用户信息失败，可能token已过期，清除认证状态
            await LogoutAsync();
            return null;
        }
    }

    public async Task<bool> RestoreAuthenticationAsync()
    {
        try
        {
            // 首先尝试使用新的会话管理系统
            var session = LocalDbService.GetCurrentUserSession();
            if (session is { Status: SessionStatus.Active })
            {
                // 检查会话是否过期
                if (session.ExpiryTime.HasValue && session.ExpiryTime.Value <= DateTime.Now)
                {
                    session.Status = SessionStatus.Expired;
                    LocalDbService.UpdateUserSession(session);
                    logger.LogInformation("会话已过期: {SessionId}", session.SessionId);
                    return false;
                }

                // 检查RememberMe设置
                if (!session.RememberMe)
                {
                    logger.LogInformation("会话未设置记住登录状态: {SessionId}", session.SessionId);
                    return false;
                }

                // 恢复会话
                Token = session.Token;
                CurrentUser = session.User.ToUserResponse();

                // 验证token是否仍然有效
                var user = await GetCurrentUserAsync();
                if (user != null)
                {
                    // 更新会话的最后活动时间
                    session.LastActivityTime = DateTime.Now;
                    LocalDbService.UpdateUserSession(session);

                    AuthenticationStatusChanged?.Invoke(this, true);
                    logger.LogInformation(
                        "成功恢复用户会话 {SessionId} for {Username}",
                        session.SessionId,
                        CurrentUser?.Username
                    );
                    return true;
                }
                else
                {
                    // Token无效，标记会话为过期
                    session.Status = SessionStatus.Expired;
                    LocalDbService.UpdateUserSession(session);
                    logger.LogWarning(
                        "会话token无效，已标记为过期: {SessionId}",
                        session.SessionId
                    );
                }
            }

            // 如果恢复失败，清除存储的信息
            ClearAuthentication();
            return false;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "恢复登录状态失败");
            ClearAuthentication();
            return false;
        }
    }
    public string? GetLastLoginUser()
    {
        try
        {
            return LocalDbService.GetLastLoginUser();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "获取最后登录用户失败");
            return null;
        }
    }    /// <summary>
         /// Refresh current user information and trigger UI updates
         /// </summary>
    public async Task<bool> RefreshCurrentUserAsync()
    {
        try
        {
            if (!IsAuthenticated)
                return false;

            var response = await Api.UserControllerApi.GetCurrentUserAsync();
            if (response?.Data != null)
            {
                CurrentUser = response.Data;

                // Trigger authentication status changed event to update UI
                AuthenticationStatusChanged?.Invoke(this, true);

                logger.LogInformation("用户信息已刷新: {Username}", CurrentUser.Username);
                return true;
            }

            return false;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "刷新用户信息失败");
            return false;
        }
    }
    private void SaveAuthentication(AuthResponse authResponse, bool rememberMe)
    {
        try
        {
            if (rememberMe)
            {
                // 使用新的会话管理系统，保存完整的会话信息（包括token）
                var session = new UserSession
                {
                    SessionId = AuthenticationServiceExtensions.GenerateSessionId(),
                    User = authResponse.User?.ToUserInfo() ?? new UserInfo(),
                    Token = authResponse.Token ?? "",
                    TokenType = authResponse.Type ?? "Bearer",
                    LoginTime = DateTime.Now,
                    LastActivityTime = DateTime.Now,
                    ExpiryTime = AuthenticationServiceExtensions.ParseTokenExpiry(
                        authResponse.Token ?? ""
                    ),
                    RememberMe = rememberMe,
                    DeviceInfo = AuthenticationServiceExtensions.GetDeviceInfo(),
                    Status = SessionStatus.Active,
                };

                LocalDbService.SaveUserSession(session);

                logger.LogInformation("已保存新的用户会话: {SessionId}", session.SessionId);
            }
            else
            {
                // 如果不记住登录状态，清除会话信息但保留用户名
                // 用户名已经在 LoginAsync 和 RegisterAsync 中通过 SaveLastLoginUser 保存
                ClearAuthentication();
                logger.LogInformation("已清除会话信息，用户名已保留用于下次登录");
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "保存认证信息失败");
        }
    }

    private void ClearAuthentication()
    {
        try
        {
            // 清除新的会话管理系统
            LocalDbService.ClearCurrentSession();
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "清除认证信息失败");
        }
    }

    private void SaveLastLoginUser(UserInfo userInfo)
    {
        try
        {
            LocalDbService.SaveLastLoginUser(userInfo);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "保存最后登录用户失败");
        }
    }
}
